# -*- coding: utf-8 -*-
import logging

import py_global

logger = logging.getLogger(__name__)

variable = 'variable'


class Class(object):

    def __init__(self):
        self.attribute = 'attribute'
        pass

    class InnerClass(object):
        """内部类"""
        pass

    # 类中可以使用控制语法
    if variable == 'variable':
        # __qualname__
        logger.info(f'qualname:{__qualname__}')
        logger.info(f'name:{__name__}')

        # 类命名空间
        logger.info(f'locals():{locals()}')

        def method(self):
            # 类命名空间不是变量作用域，完全限定
            logger.info(f'class:{self.__class__.__name__}')
            logger.info(self.attribute)
            logger.info(variable)

            # __module__
            logger.info(f'module:{self.__module__}')

            pass

        pass

    pass


class DemoClass(object):

    def method(self):
        pass


class PropertyClass(object):
    """
    装饰器@attribute.setter和@attribute.deleter修饰的方法名称必须是attribute
    """

    def __init__(self, attribute):
        self._attribute = attribute

    @property
    def attribute(self):
        return self._attribute

    @attribute.setter
    def attribute(self, parameter):
        self._attribute = parameter

    # 没有@attribute.deleter就不能删除属性
    # @attribute.deleter
    # def attribute(self):
    #     del self._attribute

    pass


"""
元类

"""


class TypeClass(type):

    def __new__(cls, class_name, base_class, attr_method_dict):
        # return type(class_name, base_class, attr_method_dict)
        # return type.__new__(cls, class_name, base_class, attr_method_dict)
        return super(TypeClass, cls).__new__(cls, class_name, base_class, attr_method_dict)

    pass


class MetaClass(object, metaclass=TypeClass):
    pass


"""
动态类型
"""


def __init__(self, instance_attribute):
    logger.info(f'class:{self.__class__.__name__}')
    self.instance_attribute = instance_attribute
    pass


def instance_method(self):
    logger.info(f'class:{self.__class__.__name__}')
    pass


# @classmethod
def class_method(cls):  # 类方法
    logger.info(f'class:{cls.__name__}')
    pass


# @staticmethod
def static_method():  # 静态方法
    pass


dict_ = {
    '__init__': __init__,
    'class_attribute': 'class_attribute',
    'instance_method': instance_method,
    'class_method': class_method,
    'static_method': static_method,
}
DynamicType = type('Dynamic', (object,), dict_)


class BaseClass(object):
    class_attr = object


if __name__ == '__main__':
    # property_class = PropertyClass(10)
    # property_class.attribute = 100
    # logger.info(f' attribute:{property_class.attribute}')
    # del property_class.attribute

    # dynamic_type = DynamicType('instance_attribute')
    # logger.info(DynamicType.class_attribute)
    # logger.info(dynamic_type.instance_attribute)
    #
    # dynamic_type.instance_method()
    # DynamicType.class_method()
    # DynamicType.static_method()

    import types

    # 使用types.new_class替换type来创建动态类，后者不支持高级特性
    ClassName = types.new_class('ClassName', (BaseClass,), exec_body=lambda ns: ns.update(dict_))

    class_list = [
        ('Float', float)
    ]
    globals().update(
        (class_name, types.new_class(
            class_name, (BaseClass,),
            exec_body=lambda ns: ns.update(class_attr=class_type)),)
        for class_name, class_type in class_list)

    pass
